/*
 * @Author: 霍格沃兹测试开发学社
 * @Desc: '更多测试开发技术探讨，请访问：https://ceshiren.com/t/topic/15860'
 */

package com.ceshiren.aitestmini.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ceshiren.aitestmini.common.Constants;
import com.ceshiren.aitestmini.dao.HogwartsTestCaseMapper;
import com.ceshiren.aitestmini.dao.HogwartsTestTaskCaseRelMapper;
import com.ceshiren.aitestmini.dao.HogwartsTestTaskMapper;
import com.ceshiren.aitestmini.dto.task.AddHogwartsTestTaskDto;
import com.ceshiren.aitestmini.dto.task.OperateJenkinsJobDto;
import com.ceshiren.aitestmini.dto.task.RequestInfoDto;
import com.ceshiren.aitestmini.dto.task.TestTaskDto;
import com.ceshiren.aitestmini.entity.HogwartsTestCase;
import com.ceshiren.aitestmini.entity.HogwartsTestTask;
import com.ceshiren.aitestmini.entity.HogwartsTestTaskCaseRel;
import com.ceshiren.aitestmini.exception.ServiceException;
import com.ceshiren.aitestmini.service.ProjectService;
//import com.ceshiren.aitestmini.util.JenkinsUtil;
import com.ceshiren.aitestmini.util.JenkinsUtil;
import com.ceshiren.aitestmini.util.R;
//import com.ceshiren.aitestmini.util.StrUtil;
import com.ceshiren.aitestmini.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.*;

@Slf4j
@Service()
@Primary
public class ProjectServiceImpl implements ProjectService {

    @Autowired
    HogwartsTestCaseMapper hogwartsTestCaseMapper;

    @Autowired
    HogwartsTestTaskMapper hogwartsTestTaskMapper;

    @Autowired
    HogwartsTestTaskCaseRelMapper hogwartsTestTaskCaseRelMapper;


    @Value("${jenkins.url}")
    private String jenkinsUrl;
    @Value("${jenkins.user}")
    private String jenkinsUserName;
    @Value("${jenkins.pwd}")
    private String jenkinsPassword;
    @Value("${jenkins.casesuffix}")
    private String jenkinsCaseSuffix;
    @Value("${jenkins.testcommand}")
    private String jenkinsTestCommand;


    /**
     * 添加用例
     * @param hogwartsTestCase
     * @return
     */
    @Override
    public R addCase(HogwartsTestCase hogwartsTestCase) {

        hogwartsTestCase.setCreateTime(new Date());
        hogwartsTestCase.setUpdateTime(new Date());

        hogwartsTestCaseMapper.insertUseGeneratedKeys(hogwartsTestCase);

        return R.ok().data(hogwartsTestCase).message("添加成功");

    }

    /**
     * 创建任务
     *
     * @param testTaskDto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public R createTask(TestTaskDto testTaskDto) {

        StringBuilder testCommand = new StringBuilder();

        AddHogwartsTestTaskDto testTask = testTaskDto.getTestTask();
        List<Integer> caseIdList = testTaskDto.getCaseIdList();

        List<HogwartsTestCase> hogwartsTestCaseList = hogwartsTestCaseMapper.selectByIds(StrUtil.list2IdsStr(caseIdList));

        makeTestCommand(testCommand, hogwartsTestCaseList);

        HogwartsTestTask hogwartsTestTask = new HogwartsTestTask();
        BeanUtils.copyProperties(testTask, hogwartsTestTask);
        hogwartsTestTask.setStatus(Constants.STATUS_ONE);
        hogwartsTestTask.setCreateTime(new Date());
        hogwartsTestTask.setUpdateTime(new Date());
        hogwartsTestTask.setTestCommand(testCommand.toString());

        hogwartsTestTaskMapper.insert(hogwartsTestTask);

        List<HogwartsTestTaskCaseRel> hogwartsTestTaskCaseRelList = new ArrayList<>();
        for (Integer caseId :caseIdList) {

            HogwartsTestTaskCaseRel hogwartsTestTaskCaseRel = new HogwartsTestTaskCaseRel();
            hogwartsTestTaskCaseRel.setCaseId(caseId);
            hogwartsTestTaskCaseRel.setTaskId(hogwartsTestTask.getId());
            hogwartsTestTaskCaseRelList.add(hogwartsTestTaskCaseRel);
        }

        hogwartsTestTaskCaseRelMapper.insertList(hogwartsTestTaskCaseRelList);
        return R.ok().message("创建成功");
    }

    /**
     * 获取用例数据
     *
     * @param hogwartsTestCase
     * @return
     */
    @Override
    public String getCaseById(HogwartsTestCase hogwartsTestCase) {

        HogwartsTestCase result = hogwartsTestCaseMapper.selectOne(hogwartsTestCase);

        if(Objects.isNull(result)){
            return "用例不存在";
        }

        return result.getCaseData();
    }

    /**
     * 执行任务
     *
     * @param requestInfoDto
     * @param hogwartsTestTask
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public R runTask(RequestInfoDto requestInfoDto, HogwartsTestTask hogwartsTestTask) throws IOException, URISyntaxException {

        HogwartsTestTask query = new HogwartsTestTask();
        query.setId(hogwartsTestTask.getId());
        HogwartsTestTask result = hogwartsTestTaskMapper.selectOne(query);
        if(Objects.isNull(result)){
            return R.error().message("任务不存在");
        }

        result.setStatus(Constants.STATUS_TWO);
        result.setUpdateTime(new Date());
        hogwartsTestTaskMapper.updateByPrimaryKeySelective(result);

        OperateJenkinsJobDto operateJenkinsJobDto = new OperateJenkinsJobDto();

        StringBuilder updateTaskStatusUrl = JenkinsUtil.makeUpdateTaskStatusUrl(requestInfoDto, hogwartsTestTask);

        operateJenkinsJobDto.setJenkinsUrl(jenkinsUrl);
        operateJenkinsJobDto.setJenkinsUserName(jenkinsUserName);
        operateJenkinsJobDto.setJenkinsPassword(jenkinsPassword);
        Map<String, String> params = new HashMap<>();
        params.put("aitestBaseUrl",requestInfoDto.getBaseUrl());
        params.put("testCommand",result.getTestCommand());
        params.put("updateStatusData",updateTaskStatusUrl.toString());
        operateJenkinsJobDto.setParams(params);

        JenkinsUtil.build2(operateJenkinsJobDto);

        return R.ok().message("成功");
    }

    /**
     * 修改任务状态
     *
     * @param hogwartsTestTask
     * @return
     */
    @Override
    public R updateStatus(HogwartsTestTask hogwartsTestTask) {

        HogwartsTestTask query = new HogwartsTestTask();
        query.setId(hogwartsTestTask.getId());
        HogwartsTestTask result = hogwartsTestTaskMapper.selectOne(query);
        if(Objects.isNull(result)){
            return R.error().message("任务不存在");
        }

        //仅执行中的任务才能改为已完成
        if(Constants.STATUS_TWO.equals(result.getStatus())){
            result.setBuildUrl(hogwartsTestTask.getBuildUrl());
            result.setUpdateTime(new Date());
            result.setStatus(Constants.STATUS_THREE);
            hogwartsTestTaskMapper.updateByPrimaryKeySelective(result);
        }

        return R.ok().message("成功");
    }

    /**
     * 获取报告
     *
     * @param taskId
     * @return
     */
    @Override
    public R getReport(Integer taskId) {

        HogwartsTestTask hogwartsTestTask = new HogwartsTestTask();
        hogwartsTestTask.setId(taskId);
        HogwartsTestTask result = hogwartsTestTaskMapper.selectOne(hogwartsTestTask);

        if(Objects.isNull(result)){
            return R.error().message("任务不存在");
        }

        String reportUrl = JenkinsUtil.getAllureReportUrl(result.getBuildUrl());

        return R.ok().data(reportUrl).message("成功");
    }

    /**
     * 用例列表查询
     *
     * @return
     */
    @Override
    public R listCase() {

        List<HogwartsTestCase> hogwartsTestCaseList = hogwartsTestCaseMapper.selectAll();

        if(Objects.isNull(hogwartsTestCaseList) || hogwartsTestCaseList.size()==0){
            return R.error().message("数据为空");
        }

        return R.ok().data(hogwartsTestCaseList).message("成功");
    }

    /**
     * 任务列表查询
     *
     * @return
     */
    @Override
    public R listTask() {

        List<HogwartsTestTask> hogwartsTestTaskList = hogwartsTestTaskMapper.selectAll();

        if(Objects.isNull(hogwartsTestTaskList) || hogwartsTestTaskList.size()==0){
            return R.error().message("数据为空");
        }

        return R.ok().data(hogwartsTestTaskList).message("成功");
    }

    /**
     *
     * @param testCommand
     * @param testCaseList
     */
    private void makeTestCommand(StringBuilder testCommand, List<HogwartsTestCase> testCaseList) {

        testCommand.append("pwd").append("\n");
        for (HogwartsTestCase hogwartsTestCase :testCaseList) {

            makeCurlCommand(testCommand, hogwartsTestCase);

            testCommand.append(jenkinsTestCommand).append(" ");
            testCommand.append(hogwartsTestCase.getCaseName())
                    .append(".")
                    .append(jenkinsCaseSuffix)
                    .append(" || true").append("\n");

        }

    }

    /**
     *  拼装下载文件的curl命令
     * @param testCommand
     * @param hogwartsTestCase
     */
    private void makeCurlCommand(StringBuilder testCommand, HogwartsTestCase hogwartsTestCase) {


        String tlp = "curl -o #caseName#.#caseSuffix# #reqUrl# || true";

        String reqUrl = "${aitestBaseUrl}/project/case/data/"+hogwartsTestCase.getId();

        String url = tlp.replace("#caseName#",hogwartsTestCase.getCaseName())
                .replace("#caseSuffix#",jenkinsCaseSuffix)
                .replace("#reqUrl#",reqUrl);

        testCommand.append(url);

    }

}
